package com.ghck.server.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ghck.message.model.BaseModel;
import com.ghck.message.model.req.EaseRegisterUserReq;
import com.ghck.message.service.EasemobService;
import com.ghck.server.dao.AjkAccountMapper;
import com.ghck.server.dao.DictionaryMapper;
import com.ghck.server.dao.EaseUserMapper;
import com.ghck.server.dao.UsersMapper;
import com.ghck.server.model.AjkAccount;
import com.ghck.server.model.Dictionary;
import com.ghck.server.model.EaseUser;
import com.ghck.server.model.Users;
import com.ghck.server.service.AjkAccountService;
import com.ghck.server.service.EaseUserService;
import com.ghck.server.service.StartUpCheckService;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

@Service
@Transactional
public class StartUpCheckServiceImpl implements StartUpCheckService {
	
	Logger logger = LoggerFactory.getLogger("StartUpCheckServiceImpl");

	@Autowired
	EaseUserService easeUserService;
	
	@Autowired
	EasemobService easemobService;

	@Autowired
	private DictionaryMapper dictionaryMapper;
	
	@Autowired
	UsersMapper usersMapper;
	
	@Autowired
	AjkAccountMapper ajkAccountMapper;
	
	@Autowired
	AjkAccountService ajkAccountService;
	
	@Autowired
	EaseUserMapper easeUserMapper;
	
	@Autowired
	Environment env;
	
	@Override
	public void startUpCheck() {
		checkoutEaseDefaultUserExists();
		
	}
	
	/**
	 * 获取默认对接的医生
	 */
	public boolean checkoutEaseDefaultUserExists(){

		//1.校验字典
		List<Dictionary> dictionarys = dictionaryMapper.findByKey("easemod_chat_doctor_list");
		if (CollectionUtils.isNotEmpty(dictionarys)) {
			if(dictionarys.size()>1){
				Dictionary update = dictionarys.get(0);
				update.setDictValue(env.getProperty("config.easemod_chat_doctor_list"));
				dictionaryMapper.update(update);
				for (int i=1 ;i<dictionarys.size(); i++) {
					dictionaryMapper.deleteById(dictionarys.get(i).getId());
				}
			}
		}else{
			Dictionary add = new Dictionary();
			add.setDictKey("easemod_chat_doctor_list");
			add.setDictValue(env.getProperty("config.easemod_chat_doctor_list"));
			dictionaryMapper.insert(add);
		}
		
		String dictValue = dictionarys.get(0).getDictValue();
		
		if(StringUtils.isEmpty(dictValue)){
			StringBuilder sb = new StringBuilder();
			sb.append(" =============== 启动检测失败 ================== ");
			sb.append("默认对接医生列表不存在，请检测 1.数据库 select * from t_dictionary where dict_key='easemod_chat_doctor_list' \n");
			sb.append("2. config.properties config.easemod_chat_doctor_list的值\n");
			System.err.println(sb.toString());
			
			logger.error(sb.toString());
			
			System.exit(1);
		}
		
		//2. 检测医生是否存在
		List<Integer> doctorUserIds = new ArrayList<Integer>();
		String[] idStrings = dictValue.split(",");
		if (ArrayUtils.isNotEmpty(idStrings)) {
			for (String idString : idStrings) {
				doctorUserIds.add(Integer.parseInt(idString));
			}
		}
		List<Users> doctorList = usersMapper.findByIds(doctorUserIds);
		List<AjkAccount> ajkAccounts = ajkAccountMapper.findByUserIds(doctorUserIds);
		Map<Integer, Users> idMapDoctor = new HashMap<Integer, Users>();
		Map<Integer, AjkAccount> userIdMapAjkAccount = new HashMap<Integer, AjkAccount>();
		if (CollectionUtils.isNotEmpty(doctorList)) {
			for(Users users : doctorList){
				idMapDoctor.put(users.getId(), users);
			}
			StringBuilder notExistsIds = new StringBuilder();
			
			for (Integer integer : doctorUserIds) {
				if(!idMapDoctor.containsKey(integer)){
					notExistsIds.append(integer).append(",");
				}
			}
			
			if (CollectionUtils.isNotEmpty(ajkAccounts)) {
				for (AjkAccount ajkAccount : ajkAccounts) {
					userIdMapAjkAccount.put(ajkAccount.getUserId(), ajkAccount);
				}
			}
			if(notExistsIds.length() > 0){
				StringBuilder sb = new StringBuilder();
				sb.append(" =============== 启动检测失败 ================== ");
				sb.append("默认对接医生,id={"+notExistsIds+"}在数据库中不存在！");
				System.err.println(sb.toString());
				
				logger.error(sb.toString());
				
				System.exit(1);
			}
			
			//不存在的Account，创建
			for (Integer integer : doctorUserIds) {
				if(!userIdMapAjkAccount.containsKey(integer)){
					AjkAccount ajkAccount = ajkAccountService.createAndInsertAccount(integer, 1);
					userIdMapAjkAccount.put(integer, ajkAccount);
				}
			}
			
			List<EaseUser> easeUsers = easeUserMapper.findByUserIds(doctorUserIds);
			Map<Integer, EaseUser> userIdMapEaseUser = new HashMap<Integer, EaseUser>();
			if (CollectionUtils.isNotEmpty(easeUsers)) {
				for (EaseUser easeUser : easeUsers) {
					userIdMapEaseUser.put(easeUser.getUserId(), easeUser);
				}
			}
			
			//检测是否在环信存在
			for (Integer integer : doctorUserIds) {
				String easeuser = easemobService.getUser(integer.toString());
				JsonObject jsonObject = BaseModel.gson.fromJson(easeuser, JsonObject.class);
				if(jsonObject.has("error")){
					/**
{
  "error": "service_resource_not_found",
  "timestamp": 1462650711643,
  "duration": 0,
  "exception": "org.apache.usergrid.services.exceptions.ServiceResourceNotFoundException",
  "error_description": "Service resource not found"
}
					 */
					EaseRegisterUserReq req = new EaseRegisterUserReq();
					req.setNickname(idMapDoctor.get(integer).getName());
					req.setPassword(userIdMapAjkAccount.get(integer).getAccessId());
					req.setUsername(integer.toString());
					easemobService.registerUser(req);
				}else{
					/*{
						  "action" : "get",
						  "path" : "/users",
						  "uri" : "http://a1.easemob.com/jinfang/aijiankangim/users/8",
						  "entities" : [ {
						    "uuid" : "f3d1df9a-1491-11e6-a06a-fbc6a3fcad0b",
						    "type" : "user",
						    "created" : 1462652777481,
						    "modified" : 1462652777481,
						    "username" : "8",
						    "activated" : true,
						    "nickname" : "养生"
						  } ],
						  "timestamp" : 1462652817345,
						  "duration" : 5,
						  "count" : 1
						}*/
				}
				if(!userIdMapEaseUser.containsKey(integer)){
					EaseUser insertEaseUser = new EaseUser();
					insertEaseUser.setNickname(idMapDoctor.get(integer).getName());
					insertEaseUser.setPassword(userIdMapAjkAccount.get(integer).getAccessId());
					insertEaseUser.setUsername(integer.toString());
					insertEaseUser.setUserId(integer);	
					easeUserMapper.insert(insertEaseUser);
				}else{
					EaseUser user = userIdMapEaseUser.get(integer);
					if(jsonObject.has("entities")){
						JsonArray entities = jsonObject.getAsJsonArray("entities");
						if(entities!=null && entities.size()==1){
							String nickname = entities.get(0).getAsJsonObject().get("nickname").getAsString();
							if(!StringUtils.equals(nickname,idMapDoctor.get(integer).getName())){
								easemobService.resetNickname(integer.toString(), idMapDoctor.get(integer).getName());
							}
							if(!StringUtils.equals(integer.toString(), user.getUsername()) 
									|| !StringUtils.equals(idMapDoctor.get(integer).getName(), user.getNickname())
											|| !StringUtils.equals(userIdMapAjkAccount.get(integer).getAccessId(), user.getPassword())){
								if(!StringUtils.equals(userIdMapAjkAccount.get(integer).getAccessId(), user.getPassword())){
									easemobService.resetUserPassword(integer.toString(), userIdMapAjkAccount.get(integer).getAccessId());
								}
								user.setNickname(idMapDoctor.get(integer).getName());
								user.setPassword(userIdMapAjkAccount.get(integer).getAccessId());
								user.setUsername(integer.toString());
								easeUserMapper.update(user);
							}
						}
					}
				}
			}
		}else{
			StringBuilder sb = new StringBuilder();
			sb.append(" =============== 启动检测失败 ================== ");
			sb.append("默认对接医生,在数据库中不存在！");
			System.err.println(sb.toString());
			
			logger.error(sb.toString());
			
			System.exit(1);
		}
		
		return true;
	}

}
